import cv2
import numpy as np
import os
import socket
import os
import shutil
import tkinter as tk
from tkinter import filedialog
import shutil
import time


addr = ('192.168.1.53', 20020)  # 目的地的IP和端口，端口不要动
FLAG = '$END$'
def sendFile_TCP(FILEPATH, ADDR, BUF=1024*64):
    sk = socket.socket()            # 初始化套接字
    sk.connect(ADDR)                # 尝试连接目标主机，如果失败会引发异常，这里为了简便没有进行异常处理
    sum = 0
    sp = '\\'
    if sp not in FILEPATH:
        sp = '/'
    filename = FILEPATH.split(sp)[-1]   # 分割路径字符串,获取文件名
    sk.send(filename.encode('utf-8'))
    with open(FILEPATH, 'rb') as f:
        while True:
            print('正在发送文件:{}  已发送 {} KB'.format(filename, int(sum/1024)))
            data = f.read(BUF)
            if not data:
                break
            sk.send(data)
            sum += len(data)
            time.sleep(0.1)
    sk.send(FLAG.encode())
    print('send_finished')
    os.system('title FileSender')
    sk.close()  # 关闭套接字


def sendtxt_TCP(txt, addr, BUF=1024*64):
    sk = socket.socket()            # 初始化套接字
    sk.connect(addr)                # 尝试连接目标主机，如果失败会引发异常，这里为了简便没有进行异常处理
    print('sending')
    sk.send(txt.encode())
    print('done')
    # sum = 0
    # sp = '\\'
    # if sp not in FILEPATH:
    #     sp = '/'
    # filename = FILEPATH.split(sp)[-1]   # 分割路径字符串,获取文件名
    # sk.send(filename.encode('utf-8'))
    # with open(FILEPATH, 'rb') as f:
    #     while True:
    #         print('正在发送文件:{}  已发送 {} KB'.format(filename, int(sum/1024)))
    #         data = f.read(BUF)
    #         if not data:
    #             break
    #         sk.send(data)
    #         sum += len(data)
    #         time.sleep(0.1)
    # sk.send(FLAG.encode())
    # print('send_finished')
    # os.system('title FileSender')
    # sk.close()  # 关闭套接字


def main():

    # 手动画框
    # 解析label_list，label_list要求按照画框的顺序写好
    root = r'predict_online'
    with open(os.path.join(root, "label_list.txt"), 'r') as file:
        label_list = file.readlines()
    label_list = [label.rstrip() for label in label_list]  # 去掉空字符
    label_list = [label for label in label_list if label != '']  # 去掉空行

    # 打开图像
    tk1 = tk.Tk()
    tk1.withdraw()
    img_path = filedialog.askopenfilename()
    src = img_path
    dst = os.path.join(root, 'origin_img.jpg')
    shutil.copy(src, dst)
    img_path_copy = dst
    img = cv2.imread(dst)
    # img = np.zeros((600, 800, 3), np.uint8)

    # 鼠标事件参数
    drawing = False
    mouse_param = {}
    mouse_param['ori_pos'] = None
    mouse_param['drawing'] = drawing
    mouse_param['x1'] = 0
    mouse_param['y1'] = 0
    mouse_param['img'] = img
    mouse_param['x2'] = 0
    mouse_param['y2'] = 0
    # mouse_param['count'] = 0
    mouse_param['label_list'] = label_list
    mouse_param['boxes_txt'] = ''
    mouse_param['label_now'] = ''

    # 鼠标画框
    cv2.namedWindow('img')
    cv2.setMouseCallback('img', on_mouse, mouse_param)
    cv2.imshow('img', img)
    cv2.rectangle(img, (0, 0), (400, 40), color=(255, 255, 255), thickness=-1)
    cv2.putText(img, 'NO Label Now!!!', (0, 36),
                fontFace=cv2.FONT_HERSHEY_TRIPLEX,
                fontScale=1, color=(0, 0, 255), thickness=1)
    while 1:
        cv2.imshow('img', img)
        key = cv2.waitKey(1) & 0xFF
        # print(key)
        if key == 255:
            pass
        elif key == 8:  # 退格，删除上一个（只能一个）
            # 删除txt
            t_label_list = mouse_param['boxes_txt'].split('/')
            print(t_label_list)
            t_label_list.pop()
            t_label_list.pop()  # 双pop，因为分割之后会有一个空的元素
            boxes_txt = ''
            for label in t_label_list:
                boxes_txt += label
                boxes_txt += '/'
            mouse_param['boxes_txt'] = boxes_txt  # 赋值回去
            print(mouse_param['boxes_txt'])
            # 在图像上画删除标志
            cv2.line(img, (mouse_param['x1'], mouse_param['y1']), (mouse_param['x2'], mouse_param['y2']),
                     color=(0, 0, 255), thickness=2, lineType=8)
        else:
            if key > 123 or key < 97:
                if key == 44:
                    mouse_param['label_now'] = 'sanitizer'
                    cv2.rectangle(img, (0, 0), (400, 40), color=(255, 255, 255), thickness=-1)
                    cv2.putText(img, mouse_param['label_now'], (0, 36),
                                fontFace=cv2.FONT_HERSHEY_TRIPLEX,
                                fontScale=1, color=(0, 0, 255), thickness=1)
                    print(mouse_param['label_now'])
                    # pass
                elif key == 46:
                    mouse_param['label_now'] = 'toothpaste'
                    cv2.rectangle(img, (0, 0), (400, 40), color=(255, 255, 255), thickness=-1)
                    cv2.putText(img, mouse_param['label_now'], (0, 36),
                                fontFace=cv2.FONT_HERSHEY_TRIPLEX,
                                fontScale=1, color=(0, 0, 255), thickness=1)
                    print(mouse_param['label_now'])
                else:
                    pass
            elif key == 27:
                pass
            else:
                if 97 <= key <= 123:
                    mouse_param['label_now'] = label_list[key - 97]
                    cv2.rectangle(img, (0, 0), (400, 40), color=(255, 255, 255), thickness=-1)
                    cv2.putText(img, mouse_param['label_now'], (0, 36),
                                fontFace=cv2.FONT_HERSHEY_TRIPLEX,
                                fontScale=1, color=(0, 0, 255), thickness=1)
                    print(mouse_param['label_now'])
                # elif key == 0:
                #     pass

        # while key != 27 or key < 97 or key > 123:
        #     cv2.waitKey() & 0xFF
        if key != 255:
            print(key)
        if key == 27:  # 按esc退出
            break
        # mouse_param['label_now'] = label_list[key - 97]
    cv2.destroyAllWindows()
    # 将画好的图片保存
    cv2.imwrite(os.path.join('predict_online', 'result.png'), mouse_param['img'], [int(cv2.IMWRITE_PNG_COMPRESSION), 0])

    # TCP发送文件
    '''
    result_file_path = os.path.join(root, 'result.png')
    print(result_file_path)
    sendFile_TCP(result_file_path, addr)
    '''

    print(mouse_param['boxes_txt'])
    # TCP发送字符串
    sendtxt_TCP(mouse_param['boxes_txt'], addr)


def on_mouse(event, x, y, flags, param):
    img = param['img']
    x1 = param['x1']
    y1 = param['y1']
    if event == cv2.EVENT_LBUTTONDOWN:  # 鼠标左键被按下
        # param['drawing'] = True
        if param['label_now'] == '':  # 屏蔽掉还没有选择时候label的状况
            return
        param['x1'], param['y1'] = x, y
        param['boxes_txt'] = param['boxes_txt'] + str(x) + ' ' + str(y) + ' '
        print('down')
    elif event == cv2.EVENT_LBUTTONUP:
        if param['label_now'] == '':  # 屏蔽掉还没有选择时候label的状况
            return
        param['x2'] = x
        param['y2'] = y
        # if param['count'] in range(len(param['label_list'])):
        cv2.rectangle(img, (x1, y1), (x, y), (255, 0, 0), 1)
        cv2.putText(img, param['label_now'], (x1, y1), color=(0, 255, 0), fontFace=cv2.FONT_HERSHEY_COMPLEX, fontScale=0.5)
        param['boxes_txt'] = param['boxes_txt'] + str(x) + ' ' + str(y) + '+'
        param['boxes_txt'] = param['boxes_txt'] + param['label_now'] + '/'  # 两个检测框之间用/分割
        # 画框计数(不在需要了)
        # param['count'] += 1
        print('up')


if __name__ == '__main__':
    main()



